home *** CD-ROM | disk | FTP | other *** search
- This file is declare.def, from which is created declare.c.
- It implements the builtins "declare" and "local" in Bash.
-
- Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
-
- This file is part of GNU Bash, the Bourne Again SHell.
-
- Bash is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 1, or (at your option) any later
- version.
-
- Bash is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License along
- with Bash; see the file COPYING. If not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $PRODUCES declare.c
-
- $BUILTIN declare
- $FUNCTION declare_builtin
- $SHORT_DOC declare [-[frxi]] name[=value] ...
- Declare variables and/or give them attributes. If no NAMEs are
- given, then display the values of variables instead.
-
- The flags are:
-
- -f to select from among function names only,
- -r to make NAMEs readonly,
- -x to make NAMEs export,
- -i to make NAMEs have the `integer' attribute set.
-
- Variables with the integer attribute have arithmetic evaluation (see
- `let') done when the variable is assigned to.
-
- Using `+' instead of `-' turns off the given attribute instead. When
- used in a function, makes NAMEs local, as with the `local' command.
- $END
-
- $BUILTIN typeset
- $FUNCTION declare_builtin
- $SHORT_DOC typeset [-[frxi]] name[=value] ...
- Obsolete. See `declare'.
- $END
-
- #include <stdio.h>
- #include "../shell.h"
-
- static int declare_internal ();
-
- /* Declare or change variable attributes. */
- int
- declare_builtin (list)
- register WORD_LIST *list;
- {
- return (declare_internal (list, 0));
- }
-
- $BUILTIN local
- $FUNCTION local_builtin
- $SHORT_DOC local name[=value] ...
- Create a local variable called NAME, and give it VALUE. LOCAL
- can only be used within a function; it makes the variable NAME
- have a visible scope restricted to that function and its children.
- $END
- int
- local_builtin (list)
- register WORD_LIST *list;
- {
- extern int variable_context;
-
- if (variable_context)
- return (declare_internal (list, 1));
- else
- {
- builtin_error ("Can only be used in a function");
- return (EXECUTION_FAILURE);
- }
- }
-
- /* The workhorse function. */
- static int
- declare_internal (list, no_modifiers)
- register WORD_LIST *list;
- int no_modifiers;
- {
- extern int variable_context, array_needs_making;
- int flags_on = 0, flags_off = 0;
- int any_failed = 0;
-
- while (list)
- {
- register char *t = list->word->word;
- int *flags;
-
- if (strcmp (t, "--") == 0)
- {
- list = list->next;
- break;
- }
-
- if (*t != '+' && *t != '-')
- break;
-
- if (no_modifiers)
- {
- builtin_error ("Modifiers not allowed");
- return (EXECUTION_FAILURE);
- }
-
- if (*t == '+')
- flags = &flags_off;
- else
- flags = &flags_on;
-
- t++;
-
- while (*t)
- {
- if (*t == 'f')
- *flags |= att_function, t++;
- else if (*t == 'x')
- *flags |= att_exported, t++, array_needs_making = 1;
- else if (*t == 'r')
- *flags |= att_readonly, t++;
- else if (*t == 'i')
- *flags |= att_integer, t++;
- else
- {
- builtin_error ("unknown option: `-%c'", *t);
- return (EXECUTION_FAILURE);
- }
- }
-
- list = list->next;
- }
-
- /* If there are no more arguments left, then we just want to show
- some variables. */
- if (!list)
- {
- /* If we didn't allow modifiers, then this is the `local' command.
- Perhaps the flag should be called `local_command' instead of
- `no_modifiers'. At any rate, only show local variables defined
- at this context level. */
- if (no_modifiers)
- {
- register SHELL_VAR **vlist;
- register int i;
-
- vlist = map_over (variable_in_context, shell_variables);
-
- if (vlist)
- {
- for (i = 0; vlist[i]; i++)
- print_assignment (vlist[i]);
-
- free (vlist);
- }
- }
- else
- {
- if (!flags_on)
- set_builtin ((WORD_LIST *)NULL);
- else
- set_or_show_attributes ((WORD_LIST *)NULL, flags_on);
- }
-
- fflush (stdout);
- return (EXECUTION_SUCCESS);
- }
-
- /* There are arguments left, so we are making variables. */
- while (list)
- {
- char *value, *name = savestring (list->word->word);
- int offset = assignment (name);
-
- if (offset)
- {
- name[offset] = '\0';
- value = name + offset + 1;
- }
- else
- {
- value = "";
- }
-
- /* If VARIABLE_CONTEXT has a non-zero value, then we are executing
- inside of a function. This means we should make local variables,
- not global ones. */
-
- if (variable_context)
- make_local_variable (name);
-
- /* If we are declaring a function, then complain about it in some way.
- We don't let people make functions by saying `typeset -f foo=bar'. */
-
- /* There should be a way, however, to let people look at a particular
- function definition by saying `typeset -f foo'. */
-
- if (flags_on & att_function)
- {
- if (offset)
- {
- builtin_error ("Can't use `-f' to make functions");
- return (EXECUTION_FAILURE);
- }
- else
- {
- SHELL_VAR *find_function (), *funvar;
- funvar = find_function (name);
-
- if (funvar)
- {
- extern char *named_function_string ();
- char *result = named_function_string
- (name, (COMMAND *)function_cell (funvar), 1);
- printf ("%s\n", result);
- }
- else
- any_failed++;
- goto hack_next_variable;
- }
- }
- else
- {
- SHELL_VAR *var;
-
- var = find_variable (name);
-
- if (!var)
- var = bind_variable (name, "");
-
- /* We are not allowed to rebind readonly variables that
- already are readonly unless we are turning off the
- readonly bit. */
- if (flags_off & att_readonly)
- flags_on &= ~att_readonly;
-
- if (value && readonly_p (var) && (!(flags_off & att_readonly)))
- {
- builtin_error ("%s: readonly variable", name);
- any_failed++;
- goto hack_next_variable;
- }
-
- var->attributes |= flags_on;
- var->attributes &= ~flags_off;
-
- if (offset)
- {
- free (var->value);
- if (integer_p (var))
- {
- long val, evalexp ();
- char *itos ();
-
- val = evalexp (value);
- var->value = itos ((int)val);
- }
- else
- var->value = savestring (value);
- }
- }
-
- stupidly_hack_special_variables (name);
-
- hack_next_variable:
- free (name);
- list = list->next;
- }
- return ((!any_failed) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
- }
-